home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
MPW_TOOL
/
TOOLS
/
TOOLS_WI
/
ICON_8
/
ICONX_FO
/
OASGN.C
< prev
next >
Wrap
Text File
|
1990-03-02
|
7KB
|
295 lines
/*
* File: oasgn.c
* Contents: asgn, rasgn, rswap, swap
*/
#include "::h:config.h"
#include "::h:rt.h"
#include "rproto.h"
#ifdef PreProcess
/* include(../M4/ops.m4) /* */
/* */
#endif /* PreProcess */
/*
* x := y - assign y to x.
*/
OpDcl(asgn,2,":=")
{
/*
* Make sure that Arg1 is a variable.
*/
if (!Var(Arg1))
RunErr(111, &Arg1);
/*
* The returned result is the variable to which assignment is being
* made.
*/
Arg0 = Arg1;
/*
* All the work is done by doasgn. Note that Arg1 is known
* to be a variable.
*/
switch (doasgn(&Arg1, &Arg2)) {
case Success:
Return;
case Failure:
Fail;
case Error:
RunErr(0, NULL);
}
}
/*
* x <- y - assign y to x.
* Reverses assignment if resumed.
*/
OpDcl(rasgn,2,"<-")
{
/*
* Arg1 must be a variable.
*/
if (!Var(Arg1))
RunErr(111, &Arg1);
/*
* The return value is the variable Arg1, so make a copy of it before
* it is dereferenced.
*/
Arg0 = Arg1;
if (DeRef(Arg1) == Error)
RunErr(0, NULL);
/*
* Assign Arg2 to Arg1 and suspend.
*/
switch (doasgn(&Arg0, &Arg2)) {
case Success:
Suspend;
break;
case Failure:
Fail;
case Error:
RunErr(0, NULL);
}
/*
* Reverse the assignment by assigning the old value
* of back and fail.
*/
if (doasgn(&Arg0, &Arg1) == Error)
RunErr(0, NULL);
Fail;
}
/*
* x <-> y - swap values of x and y.
* Reverses swap if resumed.
*/
OpDcl(rswap,2,"<->")
{
register union block *bp1, *bp2;
word adj1, adj2;
/*
* Arg1 and Arg2 must be variables.
*/
if (!Var(Arg1)) {
RunErr(111, &Arg1);
}
if (!Var(Arg2)) {
RunErr(111, &Arg2);
}
/*
* Make copies of Arg1 and Arg2 as variables in Arg0 and Arg3.
*/
Arg0 = Arg1;
Arg3 = Arg2;
adj1 = adj2 = 0;
if (Arg1.dword == D_Tvsubs && Arg2.dword == D_Tvsubs) {
bp1 = BlkLoc(Arg1);
bp2 = BlkLoc(Arg2);
if (VarLoc(bp1->tvsubs.ssvar) == VarLoc(bp2->tvsubs.ssvar) &&
Offset(bp1->tvsubs.ssvar) == Offset(bp2->tvsubs.ssvar)) {
/*
* Arg1 and Arg2 are both substrings of the same string; set
* adj1 and adj2 for use in locating the substrings after
* an assignment has been made. If Arg1 is to the right of Arg2,
* set adj1 := *Arg1 - *Arg2, otherwise if Arg2 is to the right of
* Arg1, set adj2 := *Arg2 - *Arg1. Note that the adjustment values
* may be negative.
*/
if (bp1->tvsubs.sspos > bp2->tvsubs.sspos)
adj1 = bp1->tvsubs.sslen - bp2->tvsubs.sslen;
else if (bp2->tvsubs.sspos > bp1->tvsubs.sspos)
adj2 = bp2->tvsubs.sslen - bp1->tvsubs.sslen;
}
}
if (DeRef(Arg1) == Error) {
RunErr(0, NULL);
}
if (DeRef(Arg2) == Error) {
RunErr(0, NULL);
}
/*
* Do Arg1 := Arg2
*/
switch (doasgn(&Arg0, &Arg2)) {
case Success:
break;
case Failure:
Fail;
case Error:
RunErr(0, NULL);
}
if (adj2 != 0)
/*
* Arg2 is to the right of Arg1 and the assignment Arg := Arg2 has
* shifted the position of Arg2. Add adj2 to the position of Arg2
* to account for the replacement of Arg1 by Arg2.
*/
BlkLoc(Arg3)->tvsubs.sspos += adj2;
/*
* Do Arg2 := Arg1
*/
switch (doasgn(&Arg3, &Arg1)) {
case Success:
break;
case Failure:
Fail;
case Error:
RunErr(0, NULL);
}
if (adj1 != 0)
/*
* Arg1 is to the right of Arg2 and the assignment Arg2 := Arg1 has
* shifted the position of Arg1. Add adj2 to the position of Arg1
* to account for the replacement of Arg2 by Arg1.
*/
BlkLoc(Arg0)->tvsubs.sspos += adj1;
/*
* Suspend Arg1 with the assignment in effect.
*/
Suspend;
/*
* If resumed, the assignments are undone. Note that the string position
* adjustments are opposite those done earlier.
*/
switch (doasgn(&Arg0, &Arg1)) { /* restore Arg1 */
case Success:
break;
case Failure:
Fail;
case Error:
RunErr(0, NULL);
}
if (adj2 != 0)
BlkLoc(Arg3)->tvsubs.sspos -= adj2;
switch (doasgn(&Arg3, &Arg2)) { /* restore Arg2 */
case Success:
break;
case Failure:
Fail;
case Error:
RunErr(0, NULL);
}
if (adj1 != 0)
BlkLoc(Arg0)->tvsubs.sspos -= adj1;
Fail;
}
/*
* x :=: y - swap values of x and y.
*/
OpDcl(swap,2,":=:")
{
register union block *bp1, *bp2;
word adj1, adj2;
/*
* Arg1 and Arg2 must be variables.
*/
if (!Var(Arg1)) {
RunErr(111, &Arg1);
}
if (!Var(Arg2)) {
RunErr(111, &Arg2);
}
/*
* Make copies of Arg1 and Arg2 as variables in Arg0 and Arg3.
*/
Arg0 = Arg1;
Arg3 = Arg2;
adj1 = adj2 = 0;
if (Arg1.dword == D_Tvsubs && Arg2.dword == D_Tvsubs) {
bp1 = BlkLoc(Arg1);
bp2 = BlkLoc(Arg2);
if (VarLoc(bp1->tvsubs.ssvar) == VarLoc(bp2->tvsubs.ssvar) &&
Offset(bp1->tvsubs.ssvar) == Offset(bp2->tvsubs.ssvar)) {
/*
* Arg1 and Arg2 are both substrings of the same string, set
* adj1 and adj2 for use in locating the substrings after
* an assignment has been made. If Arg1 is to the right of Arg2,
* set adj1 := *Arg1 - *Arg2, otherwise if Arg2 is to the right of
* Arg1, set adj2 := *Arg2 - *Arg1. Note that the adjustment
* values may be negative.
*/
if (bp1->tvsubs.sspos > bp2->tvsubs.sspos)
adj1 = bp1->tvsubs.sslen - bp2->tvsubs.sslen;
else if (bp2->tvsubs.sspos > bp1->tvsubs.sspos)
adj2 = bp2->tvsubs.sslen - bp1->tvsubs.sslen;
}
}
if (DeRef(Arg1) == Error) {
RunErr(0, NULL);
}
if (DeRef(Arg2) == Error) {
RunErr(0, NULL);
}
/*
* Do Arg1 := Arg2
*/
switch (doasgn(&Arg0, &Arg2)) {
case Success:
break;
case Failure:
Fail;
case Error:
RunErr(0, NULL);
}
if (adj2 != 0)
/*
* Arg2 is to the right of Arg1 and the assignment Arg1 := Arg2 has
* shifted the position of Arg2. Add adj2 to the position of Arg2
* to account for the replacement of Arg1 by Arg2.
*/
BlkLoc(Arg3)->tvsubs.sspos += adj2;
/*
* Do Arg2 := Arg1
*/
switch (doasgn(&Arg3, &Arg1)) {
case Success:
break;
case Failure:
Fail;
case Error:
RunErr(0, NULL);
}
if (adj1 != 0)
/*
* Arg1 is to the right of Arg2 and the assignment Arg2 := Arg1 has
* shifted the position of Arg1. Add adj2 to the position of Arg1 to
* account for the replacement of Arg2 by Arg1.
*/
BlkLoc(Arg0)->tvsubs.sspos += adj1;
Return;
}